package com.irdstudio.efp.report.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.irdstudio.efp.report.service.dao.RptImageMissConfigDAO;
import com.irdstudio.efp.report.service.dao.RptImageMissDAO;
import com.irdstudio.efp.report.service.domain.RptImageMiss;
import com.irdstudio.efp.report.service.domain.RptImageMissAccLoan;
import com.irdstudio.efp.report.service.domain.RptImageMissConfig;
import com.irdstudio.efp.report.service.facade.RptHandlerService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 报表处理服务
 * @author xiaojunhui<br />
 */
@Log4j2
@Service("rptHandlerService")
public class RptHandlerServiceImpl implements RptHandlerService {

    @Autowired
    private RptImageMissConfigDAO rptImageMissConfigDAO;

    @Autowired
    private RptImageMissDAO rptImageMissDAO;

    @Override
    public Boolean missImage(String dataDate) {

        log.info("影像缺失报表统计开始：业务时间="+dataDate+"|开始时间="+ LocalDateTime.now());

        //删除数据日期对应的报表数据

        try {
            int i = rptImageMissDAO.deleteByDataDate(dataDate);

            log.info("影像缺失报表统计开始：业务时间=" + dataDate + "|删除记录条数=" + i);

            //查询需要处理的产品
            List<RptImageMissConfig> rptImageMissConfigs = rptImageMissConfigDAO.queryNeedPrdList();
            if (rptImageMissConfigs == null || rptImageMissConfigs.size() < 1) {
                log.info("影像缺失报表统计：查询需要处理的产品配置为空");
                return true;
            }
            rptImageMissConfigs.forEach(rptImageMissConfig -> {
                handle(dataDate, rptImageMissConfig);
            });
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e);
        }finally {
            if (!imageMissList.isEmpty()) {
                insertList(imageMissList);
            }
        }

        log.info("影像缺失报表统计结束：业务时间="+dataDate+"|结束时间="+ LocalDateTime.now());
        return true;
    }

    /**
     * 放款客户
     * @param rptImageMissConfig
     */
    private void handle(String dataDate,RptImageMissConfig rptImageMissConfig){
        log.info("影像缺失报表统计：时间="+dataDate+"######配置="+ JSONObject.toJSONString(rptImageMissConfig));

        //获取需要处理的数据列表
        List<RptImageMissAccLoan> billNoList = getRptImageMissAccLoans(rptImageMissConfig);

        if (billNoList==null||billNoList.size()<1) {
            log.info("影像缺失报表统计：获取当前产品的放款客户为空");
            return;
        }
        //根据产品 客户类型 查询处理的影像类型列表
        List<RptImageMissConfig> rptImageMissConfigs = rptImageMissConfigDAO.queryImgTypeList(rptImageMissConfig);

        if (rptImageMissConfigs==null||rptImageMissConfigs.size()<1) {
            //根据产品和客户类型获取到的文档为空
            log.info("影像缺失报表统计：根据产品和客户类型获取到的文档为空");
            return;
        }

        List<RptImageMissConfig> tempList = new ArrayList<>();

        List<String> tempImgTypeList = new ArrayList<>();

        for (RptImageMissAccLoan rptAccLoan : billNoList) {

            //处理-判断当前借据需要统计到缺失报表的文档类型
            if (StringUtils.isNotEmpty(rptAccLoan.getLoanStartDate())) {
                getAccLoanNeedImage(dataDate,rptAccLoan,rptImageMissConfigs,tempList);
            }else {
                //时间为空那么全部都统计把
                tempList.clear();
                for (RptImageMissConfig imageMissConfig : rptImageMissConfigs) {
                    tempList.add(imageMissConfig);
                }

            }
            log.info("影像缺失报表统计：当前的处理的信息为="+JSONObject.toJSONString(rptAccLoan)+"######需要统计的文档类型为="+JSONObject.toJSONString(tempList));
            if (tempList.isEmpty()) {
                continue;
            }
            tempImgTypeList.clear();
            for (RptImageMissConfig imageMissConfig : tempList) {
                //判断当前文档是否存在明细表
                if (!checkImgExist(rptAccLoan, imageMissConfig)) {
                    //插入缺失记录到临时列表
                    tempImgTypeList.add(imageMissConfig.getImgType());
                }
            }

            if (tempImgTypeList.isEmpty()) {
                continue;
            }

            String missImgName = rptImageMissConfigDAO.queryGroupConcatImgName(tempImgTypeList);

            if (rptImageMissConfig.getCusType()==0&&rptImageMissConfigDAO.queryCfca(rptAccLoan.getBillNo()) < 1) {
                missImgName.concat(",借款合同未完成CFCA盖章");
            }
            RptImageMiss rptImageMiss = new RptImageMiss();
            rptImageMiss.setBillNo(rptAccLoan.getBillNo());
            rptImageMiss.setBusinessDate(dataDate);
            rptImageMiss.setType(getCusTypeDesc(rptImageMissConfig.getCusType()));
            rptImageMiss.setApplyDate(rptAccLoan.getLoanStartDate());
            rptImageMiss.setCusName(rptAccLoan.getCusName());
            rptImageMiss.setMissImageType(missImgName);
            rptImageMiss.setPrdId(rptAccLoan.getPrdId());
            rptImageMiss.setPrdName(rptAccLoan.getPrdName());
            InsertImgMiss(rptImageMiss);
        }
    }

    private boolean checkImgExist(RptImageMissAccLoan rptAccLoan, RptImageMissConfig imageMissConfig) {
        switch (imageMissConfig.getCusType()) {
            case 0:
                return rptImageMissConfigDAO.checkImgTypeExist(rptAccLoan,imageMissConfig.getImgType())>0;
            case 1:
                return rptImageMissConfigDAO.checkRejectLoanImgTypeExist(rptAccLoan,imageMissConfig.getImgType())>0;
            default:
                return false;
        }
    }

    /**
     * 获取客户类型描述
     * @param cusType 客户类型
     * @return
     */
    private String getCusTypeDesc(int cusType) {
        if (cusType == 0) {
            return "放款客户";
        }
        if (cusType == 1) {
            return "拒绝客户";
        }
        return "";
    }

    /**
     * 获取需要处理的数据列表
     * @param rptImageMissConfig 配置数据
     * @return
     */
    private List<RptImageMissAccLoan> getRptImageMissAccLoans(RptImageMissConfig rptImageMissConfig) {

        switch (rptImageMissConfig.getCusType()) {
            case 0:
                return rptImageMissConfigDAO.queryAccloan(rptImageMissConfig.getPrdId());
            case 1:
                return rptImageMissConfigDAO.queryRejectAccloan(rptImageMissConfig.getPrdId());
            default:
                return null;
        }
    }

    /**
     * 根据借据号获取最终需要的时间
     *
     * @param rptAccLoan
     * @param rptImageMissConfigs
     */
    private final void getAccLoanNeedImage(String dataDate, RptImageMissAccLoan rptAccLoan, List<RptImageMissConfig> rptImageMissConfigs,List<RptImageMissConfig> tempList) {


        tempList.clear();

        //获取首次用信状态

        for (RptImageMissConfig rptImageMissConfig : rptImageMissConfigs) {

            log.info(JSONObject.toJSONString(rptImageMissConfig));
            log.info(JSONObject.toJSONString(rptAccLoan));

            if (!cheDaySub(rptAccLoan.getLoanStartDate(),dataDate,rptImageMissConfig.getDateSub())) {
                continue;
            }

            if (rptImageMissConfig.getFirstLetter() == 0) {
                //判断贷款时间跟报表日期时间差 大于配置的时间 那么这笔借据的这个文档类型是需要统计到缺失报表的
                //在时间差内
                tempList.add(rptImageMissConfig);
                continue;
            }

            if (rptImageMissConfig.getFirstLetter() == 1 && rptAccLoan.getPassLetterCount() == 1) {
                //首次用信
                tempList.add(rptImageMissConfig);
                continue;
            }

            if (rptImageMissConfig.getFirstLetter() == 2 && rptAccLoan.getPassLetterCount() > 1) {
                //非首次
                tempList.add(rptImageMissConfig);
                continue;
            }

        }
    }


    private final boolean cheDaySub(String starDate,String endDate,int subDay) {

        log.info(starDate+"++++"+endDate+"+++++++"+subDay);

        if (StringUtils.isEmpty(starDate)) {
            return true;
        }

        return (LocalDate.parse(endDate).toEpochDay()-LocalDate.parse(starDate).toEpochDay()) >= subDay;
    }


    public static List<RptImageMiss> imageMissList = new ArrayList<>();

    private synchronized  void InsertImgMiss(RptImageMiss imageMiss) {

        imageMissList.add(imageMiss);

        if (imageMissList.size() >= 1000) {
            insertList(imageMissList);
        }
    }

    private  final void insertList(List<RptImageMiss> imageMissList) {
        rptImageMissDAO.insertBatch(imageMissList);
        imageMissList.clear();
    }


}
